package edu.pku.hawk.cloud;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import edu.pku.hawk.cloud.model.Agent;
import edu.pku.hawk.cloud.model.Ip;
import edu.pku.hawk.cloud.model.ResourcePrototype;
import edu.pku.hawk.cloud.model.XenHostServer;
import edu.pku.hawk.cloud.model.XenResource;

public class XmlHelper {
	private static String RESOURCE_FILE = "D:/project/CloudManager/resources_tree.xml";
	private static String XML_ATTR_ID = "id";
	private static String XML_ATTR_NAME = "name";
	private static String XML_ATTR_DESCRIPTION = "description";
	private static String XML_ATTR_TYPE = "resourceType";
	private static String XML_ATTR_ADDRESS = "address";
	private static String XML_ATTR_NETMASK = "netmask";
	private static String XML_ATTR_MAC = "mac";

	// private static String XML_ATTR_IP="ip";
	// private static String XML_ATTR_AGENT="agent";

	public static String getXML() {
		File resourceXML = new File(RESOURCE_FILE);
		BufferedReader reader;
		StringBuffer buffer = new StringBuffer();
		String s;
		try {
			reader = new BufferedReader(new FileReader(resourceXML));
			while ((s = reader.readLine()) != null) {
				buffer.append(s);
			}
		} catch (FileNotFoundException e1) {
			e1.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return buffer.toString();
	}

	public static List<XenResource> getResources(InputStream input) {
		List<XenResource> resourceList = new ArrayList<XenResource>();

		DocumentBuilderFactory builderFactory = DocumentBuilderFactory
				.newInstance();
		DocumentBuilder builder = null;
		Document document = null;
		try {
			builder = builderFactory.newDocumentBuilder();
			// document = document = builder.parse(new File(RESOURCE_FILE));
			document = document = builder.parse(input);
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		Element firstChild = (Element) document.getFirstChild();

		XenHostServer cloudResources = new XenHostServer(0, firstChild
				.getAttribute("cloud-master-name"));
		cloudResources
				.setIp(new Ip(firstChild.getAttribute("cloud-master-ip")));

		cloudResources.setNodeLabel(firstChild.getNodeName());

		cloudResources
				.setType(Integer.valueOf(firstChild.getAttribute(XML_ATTR_TYPE)));

		resourceList.add(cloudResources);

		NodeList childNodes = firstChild.getChildNodes();
		for (int index = 0; index < childNodes.getLength(); index++) {
			Node item = childNodes.item(index);
			System.out.println(item.getNodeName());
			if (item instanceof Element) {
				Element element = (Element) item;

				XenHostServer clusterResource = new XenHostServer(0, element
						.getAttribute("cluster-master-name"));
				clusterResource.setIp(new Ip(element
						.getAttribute("cluster-master-ip")));
				clusterResource.setType(Integer.valueOf(element
						.getAttribute(XML_ATTR_TYPE)));
				clusterResource.setNodeLabel(element.getNodeName());

				cloudResources.addChild(clusterResource);

				NodeList clusterChildren = element.getChildNodes();

				for (int clusterIndex = 0; clusterIndex < clusterChildren
						.getLength(); clusterIndex++) {
					item = clusterChildren.item(clusterIndex);
					if (item instanceof Element) {
						Element xenServerElement = (Element) clusterChildren
								.item(clusterIndex);
						XenHostServer xenHostServer = new XenHostServer(Integer
								.valueOf(xenServerElement
										.getAttribute(XML_ATTR_ID)),
								xenServerElement.getAttribute(XML_ATTR_NAME));

						xenHostServer.setType(Integer.valueOf(xenServerElement
								.getAttribute(XML_ATTR_TYPE)));

						Element ip = (Element) xenServerElement
								.getElementsByTagName("Ip").item(0);
						xenHostServer.setIp(new Ip(ip
								.getAttribute(XML_ATTR_ADDRESS), ip
								.getAttribute(XML_ATTR_MAC), ip
								.getAttribute(XML_ATTR_NETMASK)));

						Element agent = (Element) xenServerElement
								.getElementsByTagName("Agent").item(0);

						xenHostServer.setAgent(new Agent(Integer.valueOf(agent
								.getAttribute("id")), agent
								.getAttribute("address"), Integer.valueOf(agent
								.getAttribute("port"))));

						Element protoType = (Element) xenServerElement
								.getElementsByTagName("ResourcePrototype")
								.item(0);

						xenHostServer
								.setResourcePrototype(new ResourcePrototype(
										Integer.valueOf(protoType
												.getAttribute(XML_ATTR_ID)),
										protoType.getAttribute(XML_ATTR_NAME)));

						// NodeList resourceVM =
						// xenServerElement.getElementsByTagName("Resource");
						NodeList resourceVM = xenServerElement.getChildNodes();

						for (int vmIndex = 0; vmIndex < resourceVM.getLength(); vmIndex++) {
							Node vmNode = resourceVM.item(vmIndex);
							if ((vmNode instanceof Element)
									&& (vmNode.getNodeName().equals("Resource"))) {
								Element vmElement = (Element) vmNode;
								XenResource vmResource = new XenResource(
										Integer.valueOf(vmElement
												.getAttribute(XML_ATTR_ID)),
										vmElement.getAttribute(XML_ATTR_NAME));
								xenHostServer.addChild(vmResource);

								vmResource.setType(Integer.valueOf(vmElement
										.getAttribute(XML_ATTR_TYPE)));

								protoType = (Element) vmElement
										.getElementsByTagName(
												"ResourcePrototype").item(0);

								vmResource
										.setResourcePrototype(new ResourcePrototype(
												Integer
														.valueOf(protoType
																.getAttribute(XML_ATTR_ID)),
												protoType
														.getAttribute(XML_ATTR_NAME)));

								NodeList vmProperties = vmElement
										.getChildNodes();

								for (int proIndex = 0; proIndex < vmProperties
										.getLength(); proIndex++) {
									Node node = vmProperties.item(proIndex);
									if ((node instanceof Element)
											&& (node.getNodeName()
													.equals("Resource"))) {
										Element proElement = (Element) node;

										XenResource proResource = new XenResource(
												Integer
														.valueOf(proElement
																.getAttribute(XML_ATTR_ID)),
												proElement
														.getAttribute(XML_ATTR_NAME));
										vmResource.addChild(proResource);

										proResource.setType(Integer.valueOf(proElement
																.getAttribute(XML_ATTR_TYPE)));

										protoType = (Element) vmElement
												.getElementsByTagName(
														"ResourcePrototype")
												.item(0);
										proResource
												.setResourcePrototype(new ResourcePrototype(
														Integer
																.valueOf(protoType
																		.getAttribute(XML_ATTR_ID)),
														protoType
																.getAttribute(XML_ATTR_NAME)));
									}

								}

							}
						}

						clusterResource.addChild(xenHostServer);
					}
				}
			}

		}
		return resourceList;
	}

}
